from django.db import transaction
from rest_framework import serializers
from goods.models import SKU,SKUSpecification,GoodsCategory,SPUSpecification,SpecificationOption
from celery_tasks.static_html.tasks import get_detail_html

class SKUSpecificationSerializer(serializers.ModelSerializer):
    # SKU 具体规格序列化器

    class Meta:
        model = SKUSpecification
        fields = ('spec_id','option_id')

class SKUSerializer(serializers.ModelSerializer):
    # 商品SKU序列化器
    category = serializers.StringRelatedField(read_only=True)
    spu = serializers.StringRelatedField(read_only=True)

    spu_id = serializers.IntegerField()
    category_id = serializers.IntegerField()

    specs = SKUSpecificationSerializer(read_only=True,many=True)

    class Meta:
        model = SKU
        fields = "__all__"

        # @transaction.atomic()
        def create(self, validated_data):
            # 涉及多张表操作引入事务
            # 开启事务
            with transaction.atomic():
                # 设置保存点
                save_point = transaction.savepoint()
                try:
                    # 保存sku表
                    # 取出specs字段
                    specs = validated_data.get('specs')
                    # 将specs字段从validated_data删除
                    del validated_data['specs']
                    sku = SKU.objects.create(**validated_data)
                    # 保存sku具体规格表
                    for spec in specs:
                        SKUSpecification.objects.create(sku=sku, spec_id=spec['spec_id'], option_id=spec['option_id'])
                except:
                    transaction.savepoint_rollback(save_point)
                    raise serializers.ValidationError('数据保存失败')

                transaction.savepoint_commit(save_point)
                # 静态化生成新的详情页面
                # get_detail_html.delay(sku.id)
                return sku

        def update(self, instance, validated_data):
            # 涉及多张表操作引入事务
            # 开启事务
            with transaction.atomic():
                # 设置保存点
                save_point = transaction.savepoint()
                try:
                    # 更新sku表
                    # 取出specs字段
                    specs = validated_data.get('specs')
                    # 将specs字段从validated_data删除
                    del validated_data['specs']
                    SKU.objects.filter(id=instance.id).update(**validated_data)
                    # 更新sku具体规格表
                    for spec in specs:
                        SKUSpecification.objects.filter(sku=instance, spec_id=spec['spec_id']).update(
                            option_id=spec['option_id'])
                except:
                    transaction.savepoint_rollback(save_point)
                    raise serializers.ValidationError('数据保存失败')

                transaction.savepoint_commit(save_point)
                # 静态化生成新的详情页面
                # get_detail_html.delay(instance.id)
                return instance

class GoodsCategorySerialzier(serializers.ModelSerializer):
    """
        商品分类
    """

    class Meta:
        # 指定生成序列化字段的模型类
        model = GoodsCategory
        # 指定字段
        fields = "__all__"


class SpecificationOptionSerialzier(serializers.ModelSerializer):
    """
               商品SPU规格选项
    """

    class Meta:
        # 指定生成序列化字段的模型类
        model = SpecificationOption
        # 指定字段
        fields = ('id', 'value')


class SPUSpecificationSerialzier(serializers.ModelSerializer):
    """
            商品SPU规格
        """

    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField()

    options = SpecificationOptionSerialzier(many=True)

    class Meta:
        # 指定生成序列化字段的模型类
        model = SPUSpecification
        # 指定字段
        fields = "__all__"
